package com.njcb.ams.store.esbmodule;

import java.util.Map;
import java.util.WeakHashMap;

import javax.jws.WebService;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.njcb.ams.factory.domain.AppContext;
import com.njcb.ams.service.ParamManageService;
import com.njcb.ams.store.esbmodule.interceptor.ReqInterceptor;
import com.njcb.ams.store.esbmodule.interceptor.RspInterceptor;
import com.njcb.ams.util.AmsAssert;

/**
 * 
 * @author liuyanlong
 *
 */
@Component
public class WebServiceClient {
	private static final Logger logger = LoggerFactory.getLogger(WebServiceClient.class);
	/* 弱引用HashMap,缓存代理对象. 当对象不存在其他引用时 此引用将被垃圾回收*/
	private static Map<String, Object> loaderToCache = new WeakHashMap<String, Object>();
	@Autowired
	private ReqInterceptor reqInterceptor;
	@Autowired
	private RspInterceptor rspInterceptor;
	private WebServiceClient() {
	}
	
	public static WebServiceClient getInstance() {
		WebServiceClient webServiceClient = AppContext.getBean(WebServiceClient.class);
		if(null != webServiceClient){
			return webServiceClient;
		}
		webServiceClient = new WebServiceClient();
		return webServiceClient;
	}
	
	public static <T> T getWebService(Class<T> cla, String address){
		return getInstance().createWebService(cla, address);
	}
	
	public static <T> T getWebService(Class<T> cla){
		return getInstance().createWebService(cla);
	}
	
	private <T> T createWebService(Class<T> cla) {
		WebService webService = cla.getAnnotation(javax.jws.WebService.class);
		String address = AppContext.getBean(ParamManageService.class).getValueByName(webService.name());
		AmsAssert.notNull(address, "请在[SYS_PARAM]表中配置名称为["+webService.name()+"]的WebService服务URL");
		return createWebService(cla, address);
	}
	@SuppressWarnings("unchecked")
	private <T> T createWebService(Class<T> cla, String address){
		logger.info("\nWebService服务URL为[{}]",address);
		T service = (T)loaderToCache.get(address);
		if (null != service) {
			return service;
		}
		JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
		factoryBean.setAddress(address);
		factoryBean.setServiceClass(cla);
		if(null == reqInterceptor){
			reqInterceptor = new ReqInterceptor();
		}
		if(null == rspInterceptor){
			rspInterceptor = new RspInterceptor();
		}
		factoryBean.getOutInterceptors().add(reqInterceptor);
		factoryBean.getInInterceptors().add(rspInterceptor);
		service = (T) factoryBean.create();
		//超时时间
		Client client = ClientProxy.getClient(service);
		HTTPConduit hc = (HTTPConduit) client.getConduit();
		HTTPClientPolicy hcp = new HTTPClientPolicy();
		hcp.setConnectionTimeout(60000);
		hcp.setReceiveTimeout(60000);
		hc.setClient(hcp);
		loaderToCache.put(address, service);
		return service;
	}
	
}
